<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    
    /**
 * @Project Name: barrage.js 弹幕器
 * @description 该项目采用es5语法。兼容性好
 * @Author: wuliang
 * @Date: 2019-10-31
 * @Email: 785590408@qq.com
 * @Idea: vscode
 * 使用示例
 *    var barrage = new barrage({
 *       barrageEle:"",  //弹幕容器css选择器支持id，class  默认值：无
 *       arr:[],    //弹幕池                              默认值：无
 *       speed:50,  //弹幕速度 px/s                       默认值：50
 *       maxRow:3,  //最大行数                            默认值：3
 *       activeStyle:"#fff",  //自己发的字体颜色           默认值：白色
 *       otherStyle:"#fff",   //别人发的字体颜色           默认值：白色
 *    })
 * 方法介绍
 *    barrage.start()        //开启弹幕
 *    barrage.close()        //关闭弹幕
 *    barrage.toggleStatus() //开启与关闭自动切换
 *    barrage.add()          //向弹幕池尾部追加一条数据 弹幕最后显示 @param1:msg {String,Array} 要发送的内容 @param2: {boolean}是否是自己发的
 *    barrage.unadd()        //向弹幕池头部追加一条数据 马上显示     @param1:msg {String,Array} 要发送的内容 @param2: {boolean}是否是自己发的
 */
var barrage = function(options){
    if (typeof Object.assign != 'function') {
        Object.assign = function(target) {
            'use strict';
            if (target == null) {
            throw new TypeError('Cannot convert undefined or null to object');
            }
            target = Object(target);
            for (var index = 1; index < arguments.length; index++) {
            var source = arguments[index];
            if (source != null) {
                for (var key in source) {
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key];
                }
                }
            }
            }
            return target;
        };
    }
    this.config = Object.assign({
        speed:50,  //弹幕速度 px/s
        maxRow:3,  //最大行数
        arr:[],    //弹幕池
        arrMe:[],  //记录本人发的弹幕池
        barrageEle:"",  //弹幕容器css选择器支持id，class
        activeStyle:"red", //自己发的字体颜色
        otherStyle:"#fff",  //别人发的字体颜色
        _renderRowArr:[],
    },options);
    var timp = null;
    this.toggleStatus = function(){  //能够自动切换弹幕开启与关闭
        timp == null ? this.start() : this.close();
    }
    //["你好"]    //[{msg:"你好",status:"flase"}   ]
    this.start = function(){  //弹幕开始函数
        var cidx = 0;
        var _this = this;
        _this.close();
        timp = setInterval(function(){
            var isMeIdx = _this.config.arrMe.indexOf(_this.config.arr[0]);
            var val = _this.config.arr.splice(0,1);
            if(val.length == 0)return;
            cidx++;
            var ele = _this.renderDom(val, cidx % _this.config.maxRow,isMeIdx);
            _this.emitBarrage(ele);
        },700);
    }
    this.close = function(){     //弹幕结束器
        clearInterval(timp);
        timp = null;
    }
    this.add = function(msg,isMe){    //在弹幕池后边插入一条或多条数据
        if (Array.isArray(msg)) {
            isMe ? this.config.arrMe = this.config.arrMe.concat(msg) : ''; //临时存储在本人弹幕池
            this.config.arr = this.config.arr.concat(msg);
        }else{
            isMe ? this.config.arrMe.push(msg) : ''; 
            this.config.arr.push(msg);
        }
        console.log(this.config.arr)
    }
    this.unadd = function(msg,isMe){     //在弹幕池前边插入一条或多条数据
        if (Array.isArray(msg)) {
            isMe ? this.config.arrMe = msg.concat(this.config.arrMe) : ''; //临时存储在本人弹幕池
            this.config.arr = msg.concat(this.config.arr)
        }else{
            isMe ? this.config.arrMe.push(msg) : '';
            this.config.arr.push(msg);
        }
    }
    this.emitBarrage = function(ele){       //弹幕发射器
        var scWidth = window.screen.width;
        var eleWidth = ele.clientWidth;
        var ts = ((eleWidth + scWidth ) / this.config.speed) + Math.floor(Math.random() * 6);
        ele.style.transition = ts + "s linear";
        ele.style.left = "-" +eleWidth + "px";
        setTimeout(function(){
            ele.remove();
        },ts * 1000);
    }
    this.renderDom = function(msg,row,isMeIdx){    //弹幕节点生成器
        var barrageBox = document.querySelector(this.config.barrageEle);
        var arr = this._renderRowArr;
        var div = document.createElement('div');
        div.innerHTML = msg;
        div.className = "barrage-item";
        div.style.top = arr[row] + "px";
        div.style.left = '100vw';
        //判断是否本人发送弹幕池
        if (isMeIdx !== -1) {
            div.style.color = this.config.activeStyle;
            this.config.arrMe.splice(isMeIdx,1);
        }
        barrageBox.appendChild(div);
        return div
    }
    this.renderRow = function(){
        var rowArr = [];
        var barrageBox = document.querySelector(this.config.barrageEle);
        var barrageBoxHgt = barrageBox.clientHeight;
        var tHeight = (barrageBoxHgt / (this.config.maxRow + 1))
        for (var j = 0; j < this.config.maxRow; j++) {
            rowArr.push(Math.floor(tHeight * (j+1) - 15))
        }
        this._renderRowArr = rowArr;
    }
    this.init = function(){  //初始化弹幕器
        var style = document.createElement('style');
        style.innerHTML = '.barrage-item{width: auto;height: 30px;padding: 5px;color: '+this.config.otherStyle+';white-space: nowrap;position: absolute;}';
        document.head.appendChild(style);
        var barrageBox = document.querySelector(this.config.barrageEle);
        var barrageBoxHgt = barrageBox.clientHeight;
        var max = (barrageBoxHgt / 30);
        Math.floor(max) < this.config.maxRow ? this.config.maxRow = Math.floor(max) : "";
        this.renderRow();
    }
    this.init()//初始化弹幕器
}
window ? window.barrage = barrage : "";
    
    // 1 是switch 按钮
    // 2 是区域移动
    // 3 是弹幕系统
    
    </script>
</body>
</html>